From a67183644e4bc58e29f44bb42f3a1e19ca2ef338 Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Tue, 18 Nov 2008 15:55:14 +0000 Subject: [PATCH] x86: Re-initialise HPET on resume from S3 Signed-off-by: Guanqun Lu Signed-off-by: Kevin Tian Signed-off-by: Keir Fraser --- xen/arch/x86/hpet.c | 7 +------ xen/arch/x86/time.c | 20 +++++++++++++++++--- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/xen/arch/x86/hpet.c b/xen/arch/x86/hpet.c index 83ab2f1887..5c2bc02885 100644 --- a/xen/arch/x86/hpet.c +++ b/xen/arch/x86/hpet.c @@ -264,15 +264,10 @@ int hpet_legacy_irq_tick(void) u64 hpet_setup(void) { - static u64 hpet_rate; - static int initialised; + u64 hpet_rate; u32 hpet_id, hpet_period, cfg; int i; - if ( initialised ) - return hpet_rate; - initialised = 1; - if ( hpet_address == 0 ) return 0; diff --git a/xen/arch/x86/time.c b/xen/arch/x86/time.c index f3cd4234fe..acd8750b7d 100644 --- a/xen/arch/x86/time.c +++ b/xen/arch/x86/time.c @@ -60,6 +60,7 @@ struct platform_timesource { u64 frequency; u64 (*read_counter)(void); int (*init)(struct platform_timesource *); + void (*resume)(struct platform_timesource *); int counter_bits; }; @@ -396,12 +397,21 @@ static int init_hpet(struct platform_timesource *pts) return 1; } +static void resume_hpet(struct platform_timesource *pts) +{ + u64 hpet_rate = hpet_setup(); + + BUG_ON(hpet_rate == 0); + pts->frequency = hpet_rate; +} + static struct platform_timesource plt_hpet = { .name = "HPET", .read_counter = read_hpet_count, .counter_bits = 32, - .init = init_hpet + .init = init_hpet, + .resume = resume_hpet }; /************************************************************ @@ -566,6 +576,10 @@ static void platform_time_calibration(void) static void resume_platform_timer(void) { + /* Timer source can be reset when backing from S3 to S0 */ + if ( plt_src.resume ) + plt_src.resume(&plt_src); + /* No change in platform_stime across suspend/resume. */ platform_timer_stamp = plt_stamp64; plt_stamp = plt_src.read_counter(); @@ -1214,13 +1228,13 @@ int time_resume(void) { /*u64 tmp = */init_pit_and_calibrate_tsc(); - disable_pit_irq(); - /* Disable this while calibrate_tsc_ap() also is skipped. */ /*set_time_scale(&this_cpu(cpu_time).tsc_scale, tmp);*/ resume_platform_timer(); + disable_pit_irq(); + init_percpu_time(); do_settime(get_cmos_time() + cmos_utc_offset, 0, NOW()); -- 2.30.2